window.APP_SDK = window.APP_SDK || false;
/**
 * 删除数组
 * @param n
 * @return {*}
 */
Array.prototype.remove = function (n) {
	if (n < 0) {
		return this;
	} else {
		return this.slice(0, n).concat(this.slice(n + 1, this.length));
	}
};

/**
 * 空匿名函数
 */
window.bAnonymous = function () {
};

/**
 * 对话框模块
 * @constructor
 */
function BDialog() {
	this.toastSuccessIcon = BDialog.options.toastSuccessIcon;
	this.toastErrorIcon   = BDialog.options.toastErrorIcon;
	this.toastIconPrefix  = BDialog.options.toastIconPrefix;
	this.showCallback     = BDialog.options.showCallback;
	this.hideCallback     = BDialog.options.hideCallback;
}

BDialog.options = {
	toastSuccessIcon : 'check',
	toastErrorIcon   : 'exclamation-circle',
	toastIconPrefix  : 'fa fa-3x fa-',
	showCallback     : window.bAnonymous,
	hideCallback     : window.bAnonymous
};
/**
 * 设置弹窗配置
 * @param {Object|String} options 配置合集或配置名称
 * @param {Object} value 配置值
 */
BDialog.setOptions = function (options, value) {
	if (typeof options === 'string') {
		BDialog.options[options] = value;
	} else {
		BDialog.options = $.extend({}, BDialog.options, options);
	}
};
/**
 * 设置显示回调
 * @param {Function} callback
 */
BDialog.prototype.setShowCallback = function (callback) {
	this.showCallback = typeof callback === 'function' ? callback : window.bAnonymous;
};
/**
 * 设置销毁回调
 * @param {Function} callback
 */
BDialog.prototype.setHideCallback = function (callback) {
	this.hideCallback = typeof callback === 'function' ? callback : window.bAnonymous;
};
/**
 * 弹出一个alert对话框
 * @param {String} message
 * @param {Function} okCallback
 * @param {String} okVal
 * @return {layer}
 */
BDialog.prototype.alert = function (message, okCallback, okVal) {
	message = message || '';
	okVal   = okVal || '确定';

	if (window.APP_SDK) {
		APP_SDK.ready(function () {
			APP_SDK.alert(message, okCallback);
		});
	} else {
		return layer.open({
			className  : 'b-dialog-alert',
			shadeClose : false,
			title      : '消息提醒',
			content    : message,
			btn        : okVal,
			success    : this.showCallback,
			end        : this.hideCallback,
			yes        : function (index) {
				var status = true;
				if (typeof okCallback === 'function') {
					status = okCallback(index);
				}

				if (false !== status) {
					layer.close(index);
				}
			}
		});
	}

};
/**
 * 弹出一个confirm对话框
 * @param {String} message
 * @param {Function} okCallback
 * @param {Function} cancelCallback
 * @param {String} okVal
 * @param {String} cancelVal
 * @return {layer}
 */
BDialog.prototype.confirm = function (message, okCallback, cancelCallback, okVal, cancelVal) {
	message   = message || '';
	okVal     = okVal || '确定';
	cancelVal = cancelVal || '取消';

	if (window.APP_SDK) {
		APP_SDK.ready(function () {
			APP_SDK.confirm(message, okCallback, cancelCallback);
		});
	} else {
		return layer.open({
			className  : 'b-dialog-confirm',
			shadeClose : false,
			title      : "消息提醒",
			content    : message,
			btn        : [okVal, cancelVal],
			success    : this.showCallback,
			end        : this.hideCallback,
			yes        : function (index) {
				var status = true;
				if (typeof okCallback === 'function') {
					status = okCallback(index);
				}

				if (false !== status) {
					layer.close(index);
				}
			},
			no         : function (index) {
				var status = true;
				if (typeof cancelCallback === 'function') {
					status = cancelCallback(index);
				}

				if (false !== status) {
					layer.close(index);
				}
			}
		});
	}
};
/**
 * 弹出一个toast对话框
 * @param {String} message
 * @param {Boolean} long
 * @return {layer}
 */
BDialog.prototype.toast = function (message, long) {
	message = message || '';
	long    = long === undefined ? false : long;
	if (window.APP_SDK) {
		APP_SDK.ready(function () {
			APP_SDK.toast(message, long);
		});
	} else {
		return layer.open({
			content : message,
			success : this.showCallback,
			end     : this.hideCallback,
			skin    : 'msg',
			time    : long ? 4 : 2
		});
	}
};
/**
 * 弹出一个图标toast
 * @param {String} message
 * @param {String} icon
 * @param {Boolean} long
 * @return {layer}
 */
BDialog.prototype.toastIcon = function (message, icon, long) {
	message = message || '';
	icon    = icon || 'fa fa-check';
	long    = long === undefined ? false : long;

	if (window.APP_SDK) {
		this.toast(message, long);
	} else {
		return layer.open({
			className : 'b-dialog-toast-icon',
			content   : '<div class="text-center"><div class="toast-icon"><i class="' + this.toastIconPrefix + icon + '"></i></div><div class="message">' + message + '</div></div>',
			success   : this.showCallback,
			end       : this.hideCallback,
			skin      : 'msg',
			time      : long ? 4 : 2
		});
	}
};
/**
 * 弹出一个toast成功对话框
 * @param {String} message
 * @param {Boolean} long
 * @return {layer}
 */
BDialog.prototype.toastSuccess = function (message, long) {
	return this.toastIcon(message, this.toastSuccessIcon, long);
};
/**
 * 弹出一个toast失败对话框
 * @param {String} message
 * @param {Boolean} long
 * @return {layer}
 */
BDialog.prototype.toastError = function (message, long) {
	return this.toastIcon(message, this.toastErrorIcon, long);
};
/**
 * 弹出一个toast成功对话框N秒后跳转
 * @param {String} message
 * @param {String} url
 * @param {Number} delay N秒后跳转
 * @return {layer}
 */
BDialog.prototype.toastSuccessGoUrl = function (message, url, delay) {
	var layer = this.toastSuccess(message);
	delay     = delay || 1;

	setTimeout(function () {
		self.location.href = url;
	}, delay * 1000);

	return layer;
};
/**
 * 弹出一个toast成功对话框N秒后跳转
 * @param {String} message
 * @param {String} url
 * @param {Number} delay N秒后跳转
 * @return {layer}
 */
BDialog.prototype.toastErrorGoUrl = function (message, url, delay) {
	var layer = this.toastError(message);
	delay     = delay || 2;

	setTimeout(function () {
		self.location.href = url;
	}, delay * 1000);

	return layer;
};

/**
 * 等待框模块
 * @param message
 */
function BDialogPending(message) {
	var me = this;
	if (window.APP_SDK) {
		me.index = APP_SDK.pending(message);
	} else {
		this.index = layer.open({
			shadeClose : false,
			className  : 'b-dialog-pending',
			type       : 2,
			success    : this.showCallback,
			end        : this.hideCallback,
			content    : message
		});
	}
}

/**
 * 更新消息
 * @param message
 * @return {BDialogPending}
 */
BDialogPending.prototype.update = function (message) {
	var me = this;
	if (window.APP_SDK) {
	} else {
		$('#' + 'layui-m-layer' + this.index).find('.layui-m-layercont p').html(message);
	}

	return this;
};
/**
 * 关闭pending
 * @return {BDialogPending}
 */
BDialogPending.prototype.close = function () {
	if (this.index === null) {
		return this;
	}

	var me = this;
	if (window.APP_SDK) {
		APP_SDK.ready(function () {
			me.index.close();
		});
	} else {
		layer.close(this.index);
	}

	return this;
};
/**
 * 弹出一个等待对话框
 * @param message
 * @return {BDialogPending}
 */
BDialog.prototype.pending = function (message) {
	return new BDialogPending(message);
};

/**
 * 全屏对话框
 * @param url
 * @param html
 * @param direction
 * @constructor
 */
function BDialogFull(url, html, direction) {
	this.index = layer.open({
		type      : 1,
		content   : url ? '<iframe src="' + url + '"></iframe>' : html,
		className : 'b-dialog-full',
		anim      : direction || 'up',
		style     : 'position:fixed; left:0; top:0; width:100%; height:100%; border: none; -webkit-animation-duration: .5s; animation-duration: .5s;',
		end       : function () {
			$('body').removeClass('b-dialog-open');
		},
		success   : function (o) {
			setTimeout(function () {
				var pending = bDialog.pending('.....');
				$(o).find('iframe').load(function () {
					pending.close();
				});
			}, 50);
		}
	});

	$('body').addClass('b-dialog-open');
}

/**
 * 关闭对话框
 */
BDialogFull.prototype.close = function () {
	if (this.index === null) {
		return this;
	}
	layer.close(this.index);

	return this;
};
/**
 * 弹出一个HTML全屏对话框
 * @param {String} html
 * @param {String} direction 方向
 * @return {BDialogFull}
 */
BDialog.prototype.fullHtml = function (html, direction) {
	return new BDialogFull('', html, direction);
};
/**
 * 弹出一个Iframe全屏对话框
 * @param {String} url¬
 * @param {String} direction 方向
 * @return {BDialogFull}
 */
BDialog.prototype.fullIFrame = function (url, direction) {
	return new BDialogFull(url, '', direction);
};

window.bDialog = new BDialog();

/**
 * 数据解析模块
 * @constructor
 */
function BParseResult() {
	this.parseCallback = null;
	this.bindCodeList  = {};
}

/**
 * 执行解析数据
 * @param {String} result
 * @param {Function} success (Object json) void
 * @param {Function} error (Object json) void
 * @param {Function} complete (Object json) boolean 返回false阻止继续解析
 */
BParseResult.prototype.parse = function (result, success, error, complete) {
	var json;
	// 自定义解析
	if (typeof this.parseCallback == 'function') {
		json = this.parseCallback(result) || {};
		if (!json.hasOwnProperty('status')) {
			bDialog.toastError("parse return not has status", false);
			return;
		}
		if (typeof json.status !== 'boolean') {
			bDialog.toastError("parse return in status must be boolean", false);
			return;
		}
		if (!json.hasOwnProperty('code')) {
			bDialog.toastError("parse return not has code", false);
			return;
		}
		if (!json.hasOwnProperty('message')) {
			bDialog.toastError("parse return not has message", false);
			return;
		}
		if (!json.hasOwnProperty('url')) {
			bDialog.toastError("parse return not has url", false);
			return;
		}
		if (!json.hasOwnProperty('result')) {
			bDialog.toastError("parse return not has result", false);
			return;
		}
	} else {
		// 校验JSON数据
		result = $.trim(result);
		if ('{' !== result.charAt(0) || '}' !== result.charAt(result.length - 1)) {
			bDialog.toastError("参数错误或网络异常", false);
			return;
		}

		// 解析JSON数据
		json = JSON.parse(result);
		if (json === null || json === undefined || !json) {
			bDialog.toastError("参数错误或网络异常", false);
			return;
		}
	}

	// 解析完成
	if (typeof complete === 'function') {
		if (false === complete(json)) {
			return;
		}
	}

	// 消息代码回调
	var callbackList   = this.bindCodeList[json.code] || [];
	var callbackLength = callbackList.length;

	// 倒序遍历回调
	for (var i = callbackLength - 1; i >= 0; i--) {
		var requestCode = callbackList[i].requestCode || 0;
		var callback    = callbackList[i].callback || null;

		// 回调不为方法跳过
		if (typeof callback !== 'function') {
			continue;
		}

		// 如果回调返回错误，则直接跳出
		if (false === callback(requestCode, json)) {
			return;
		}
	}

	// 成功
	if (json.status) {
		if (typeof success === 'function') {
			success(json);
		}
	} else {
		if (typeof error === 'function') {
			error(json);
		}
	}
};
/**
 * 设置JSON数据解析回调
 * @param {Function} callback(String jsonString) 回调方法
 * @return BParseResult
 */
BParseResult.prototype.setParse = function (callback) {
	this.parseCallback = callback;

	return this;
};
/**
 * 绑定消息代码回调
 * @param {Number} resultCode 消息代码
 * @param {Number} requestCode 请求代码
 * @param {Function} callback (Number requestCode, Object json) 回调方法
 * @return BParseResult
 */
BParseResult.prototype.bindCode = function (resultCode, requestCode, callback) {
	this.bindCodeList[resultCode] = this.bindCodeList[resultCode] || [];
	this.bindCodeList[resultCode].push({
		requestCode : requestCode,
		callback    : callback
	});

	return this;
};
window.bParseResult = new BParseResult();

/**
 * 请求模块
 * @constructor
 */
function BRequest() {
	this.isPost           = BRequest.options.isPost;
	this.requestParams    = BRequest.options.requestParams;
	this.requestUrl       = BRequest.options.requestUrl;
	this.isCache          = BRequest.options.isCache;
	this.isPendingModel   = BRequest.options.isPendingModel;
	this.pendingMessage   = BRequest.options.pendingMessage;
	this.beforeCallback   = BRequest.options.beforeCallback;
	this.completeCallback = BRequest.options.completeCallback;
	this.successCallback  = BRequest.options.successCallback;
	this.errorCallback    = BRequest.options.errorCallback;
}

BRequest.options = {
	isPost           : true,
	requestParams    : {},
	requestUrl       : document.URL,
	isCache          : false,
	isPendingModel   : true,
	pendingMessage   : '请稍候...',
	beforeCallback   : window.bAnonymous,
	completeCallback : window.bAnonymous,
	successCallback  : function (json) {
		bDialog.toastSuccess(json.message || 'success');
	},
	errorCallback    : function (json) {
		bDialog.toastError(json.message || 'error');
	}
};
/**
 * 设置全局参数
 * @param {Object|String} options 配置合集或配置名称
 * @param {Object} value 配置值
 */
BRequest.setOptions = function (options, value) {
	if (typeof options === 'string') {
		BRequest.options[options] = value;
	} else {
		BRequest.options = $.extend(BRequest.options, options);
	}
};
/**
 * 设置是否显示pending模态框
 * @param {Boolean} isPendingModel
 * @param {String} pendingMessage
 */
BRequest.prototype.setPendingModel = function (isPendingModel, pendingMessage) {
	this.isPendingModel = isPendingModel;
	if (pendingMessage) {
		this.pendingMessage = pendingMessage;
	}
	return this;
};
/**
 * 执行请求
 */
BRequest.prototype.request = function () {
	var me               = this;
	var pending          = null;
	var completeCallback = function (json) {
		if (pending != null) {
			pending.close();
		}

		return me.completeCallback.call(me, json);
	};
	var successCallback  = function (json) {
		me.successCallback.call(me, json);
	};
	var errorCallback    = function (json) {
		me.errorCallback.call(me, json);
	};

	// 请求回调
	if (false === me.beforeCallback.call(me)) {
		return;
	}

	// 请求等待模态框
	if (me.isPendingModel) {
		pending = bDialog.pending(me.pendingMessage);
	}

	// POST请求
	if (me.isPost) {
		$.post(me.requestUrl, this.requestParams, function (result) {
			bParseResult.parse(result, me.successCallback, me.errorCallback, completeCallback);
		}, 'html');
	}

	// GET请求
	else {
		// 禁止缓存
		if (!me.isCache) {
			me.addRequestParam('__bt', Math.random());
		}
		$.get(me.requestUrl, me.requestParams, function (result) {
			bParseResult.parse(result, successCallback, errorCallback, completeCallback);
		}, 'html');
	}
};
/**
 * 设置GET请求是否启用缓存，默认不启用
 * @param isCache
 * @return {BRequest}
 */
BRequest.prototype.setRequestIsCache = function (isCache) {
	this.isCache = isCache;

	return this;
};
/**
 * 设置请求链接
 * @param {String} url
 * @return {BRequest}
 */
BRequest.prototype.setUrl = function (url) {
	this.requestUrl = url || document.URL;

	return this;
};
/**
 * 设置是否POST请求
 * @param {Boolean} isPost 是否POST请求
 * @return {BRequest}
 */
BRequest.prototype.setRequestIsPost = function (isPost) {
	this.isPost = isPost;

	return this;
};
/**
 * 设置请求参数
 * @param {Object} params
 * @return {BRequest}
 */
BRequest.prototype.setRequestParams = function (params) {
	this.requestParams = params;
	return this;
};
/**
 * 添加请求参数
 * @param {String} name 参数名
 * @param {String} value 参数值
 * @return {BRequest}
 */
BRequest.prototype.addRequestParam = function (name, value) {
	this.requestParams[name] = value;

	return this;
};
/**
 * 清理请求参数
 */
BRequest.prototype.clearRequestParams = function () {
	this.requestParams = {};
};
/**
 * 设置请求成功回调
 * @param {Function} callback (Object json) void
 * @return {BRequest}
 */
BRequest.prototype.setSuccess = function (callback) {
	this.successCallback = typeof callback === 'function' ? callback : this.successCallback;

	return this;
};
/**
 * 设置请求失败回调
 * @param {Function} callback (Object json) void
 * @return {BRequest}
 */
BRequest.prototype.setError = function (callback) {
	this.errorCallback = typeof callback === 'function' ? callback : this.errorCallback;

	return this;
};
/**
 * 设置请求完成回调
 * @param {Function} callback (Object json) 返回false阻止继续success和error的执行
 * @return {BRequest}
 */
BRequest.prototype.setComplete = function (callback) {
	this.completeCallback = typeof callback === 'function' ? callback : this.completeCallback;

	return this;
};
/**
 * 设置请求前回调
 * @param {Function} callback = Boolean 返回false阻止提交
 * @return {BRequest}
 */
BRequest.prototype.setBefore = function (callback) {
	this.beforeCallback = typeof callback === 'function' ? callback : this.beforeCallback;

	return this;
};

/**
 * 滚动加载模块
 */
var BLoadData = function () {
	this.params           = BLoadData.options.params;
	this.url              = BLoadData.options.url;
	this.dataTarget       = BLoadData.options.dataTarget;
	this.pageKey          = BLoadData.options.pageKey;
	this.scrollTarget     = BLoadData.options.scrollTarget;
	this.windowHeight     = BLoadData.options.windowHeight;
	this.moreTarget       = BLoadData.options.moreTarget;
	this.pageStartIndex   = BLoadData.options.pageStartIndex;
	this.page             = 0;
	this.loadStatus       = false;
	this.isFirstLoad      = true;
	this.completeCallback = null;
	this.timer            = null;

	// 为空模版
	this.emptyMessage  = BLoadData.options.emptyMessage;
	this.emptyTemplate = BLoadData.options.emptyTemplate;

	// 错误模版
	this.errorMessage  = BLoadData.options.errorMessage;
	this.errorTemplate = BLoadData.options.errorTemplate;

	// 加载提示
	this.moreMessage  = BLoadData.options.moreMessage;
	this.moreTemplate = BLoadData.options.moreTemplate;

	// 没有更多数据模版
	this.emptyMoreMessage  = BLoadData.options.emptyMoreMessage;
	this.emptyMoreTemplate = BLoadData.options.emptyMoreTemplate;

	// 更多数据加载中
	this.moreLoadMessage  = BLoadData.options.moreLoadMessage;
	this.moreLoadTemplate = BLoadData.options.moreLoadTemplate;

	// 数据首次加载
	this.loadMessage  = BLoadData.options.loadMessage;
	this.loadTemplate = BLoadData.options.loadTemplate;
};
/**
 * 全局参数
 * @type {Object}
 */
BLoadData.options = {
	params           : {},
	url              : document.URL,
	dataTarget       : null,
	moreTarget       : null,
	pageKey          : 'page',
	scrollTarget     : $(document),
	windowHeight     : $(window).height(),
	completeCallback : window.bAnonymous,
	pageStartIndex   : 0,

	// 为空模版
	emptyMessage  : '暂无数据',
	emptyTemplate : '<div class="empty-info"><i class="fa fa-file-text-o fa-3x"></i><div class="space-10"></div><div class="tip">__MESSAGE__</div></div>',

	// 错误模版
	errorMessage  : '',
	errorTemplate : '<div class="empty-info"><i class="fa fa-file-text-o fa-3x"></i><div class="space-10"></div><div class="tip">__MESSAGE__</div></div>',

	// 加载提示
	moreMessage  : '上拉加载更多',
	moreTemplate : '<i class="fa fa-long-arrow-up"></i> __MESSAGE__',

	// 没有更多数据模版
	emptyMoreMessage  : '没有更多数据了',
	emptyMoreTemplate : '__MESSAGE__',

	// 更多数据加载中
	moreLoadMessage  : '数据加载中...',
	moreLoadTemplate : '<i class="fa fa-spinner fa-pulse"></i> __MESSAGE__',

	// 数据首次加载
	loadMessage  : '加载中...',
	loadTemplate : '<div class="pending-tip"><i class="fa fa-spinner fa-pulse fa-2x"></i><div class="space-10"></div><div class="tip">__MESSAGE__</div></div>'

};
/**
 * 设置全局配置
 * @param {Object|String} options 配置合集或配置名称
 * @param {Object} value 配置值
 */
BLoadData.setOptions = function (options, value) {
	if (typeof options === 'string') {
		BLoadData.options[options] = value;
	} else {
		BLoadData.options = $.extend({}, BLoadData.options, options);
	}
};
/**
 * 设置数据容器对象
 * @param {Function} callback
 * @return {BLoadData}
 */
BLoadData.prototype.setCompleteCallback = function (callback) {
	this.completeCallback = callback;
	return this;
};
/**
 * 设置数据容器对象
 * @param {String|Object} dataTarget
 * @return {BLoadData}
 */
BLoadData.prototype.setDataTarget = function (dataTarget) {
	this.dataTarget = $(dataTarget);
	return this;
};
/**
 * 设置更多展示容器对象
 * @param {String|Object} moreTraget
 * @return {BLoadData}
 */
BLoadData.prototype.setMoreTarget = function (moreTraget) {
	this.moreTraget = $(moreTraget);
	return this;
};
/**
 * 设置滚动容器对象
 * @param {String|Object} scrollTarget
 * @return {BLoadData}
 */
BLoadData.prototype.setScrollTarget = function (scrollTarget) {
	this.scrollTarget = $(scrollTarget);
	return this;
};
/**
 * 设置请求URL
 * @param {String} url
 * @return {BLoadData}
 */
BLoadData.prototype.setUrl = function (url) {
	this.url = url;
	return this;
};
/**
 * 设置分页参数起始页码
 * @param {Number} index
 * @return {BLoadData}
 */
BLoadData.prototype.setPageStartIndex = function (index) {
	this.pageStartIndex = index;
	this.page           = index;
	return this;
};
/**
 * 设置分页请求参数
 * @param {String} key
 * @return {BLoadData}
 */
BLoadData.prototype.setPageKey = function (key) {
	this.pageKey = key;
	return this;
};
/**
 * 设置请求参数
 * @param {String} key
 * @param {String} value
 * @return {BLoadData}
 */
BLoadData.prototype.addParam = function (key, value) {
	this.params[key] = value;
	return this;
};
/**
 * 设置数据为空的提示内容
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setEmptyTemplate = function (message, template) {
	if (true === template) {
		this.emptyTemplate = message;
	} else {
		if (message) {
			this.emptyMessage = message;
		}
		if (template) {
			this.emptyTemplate = template;
		}
	}
	return this;
};
/**
 * 设置加载更多提示
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setMoreTemplate = function (message, template) {
	if (true === template) {
		this.moreTemplate = message;
	} else {
		if (message) {
			this.moreMessage = message;
		}
		if (template) {
			this.moreTemplate = template;
		}
	}
	return this;
};
/**
 * 设置没有更多内容提示
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setEmptyMoreTemplate = function (message, template) {
	if (true === template) {
		this.emptyMoreTemplate = message;
	} else {
		if (message) {
			this.emptyMoreMessage = message;
		}
		if (template) {
			this.emptyMoreTemplate = template;
		}
	}
	return this;
};
/**
 * 设置错误提示
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setErrorTemplate = function (message, template) {
	if (true === template) {
		this.errorTemplate = message;
	} else {
		if (message) {
			this.errorMessage = message;
		}
		if (template) {
			this.errorTemplate = template;
		}
	}
	return this;
};
/**
 * 设置首次加载提示
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setLoadTemplate = function (message, template) {
	if (true === template) {
		this.loadTemplate = message;
	} else {
		if (message) {
			this.loadMessage = message;
		}
		if (template) {
			this.loadTemplate = template;
		}
	}
	return this;
};
/**
 * 设置更多加载提示
 * @param {String} message 提示内容
 * @param {String} template 模板内容 __MESSAGE__ 为提示内容变量
 * @return {BLoadData}
 */
BLoadData.prototype.setMoreLoadTemplate = function (message, template) {
	if (true === template) {
		this.moreLoadTemplate = message;
	} else {
		if (message) {
			this.moreLoadMessage = message;
		}
		if (template) {
			this.moreLoadTemplate = template;
		}
	}
	return this;
};
/**
 * 设置全部展示，不下拉加载
 * @param {Boolean} status
 * @return {BLoadData}
 */
BLoadData.prototype.setShowAll = function (status) {
	status         = typeof status === 'boolean' ? status : false;
	this.isShowAll = status;

	return this;
};
/**
 * 数据加载
 * @return {BLoadData}
 */
BLoadData.prototype.request = function () {
	var me = this;

	// 分页码
	me.params[me.pageKey] = me.page;

	// 加载数据
	if (me.loadStatus) {
		return this;
	}

	// 加载提示
	if (me.isFirstLoad) {
		me.dataTarget.html(me.loadTemplate.replace('__MESSAGE__', me.loadMessage));
		me.moreTraget.hide();
	} else {
		me.moreTraget.html(me.moreLoadTemplate.replace('__MESSAGE__', me.moreLoadMessage)).show();
	}

	// 执行加载
	$.BRequest()
		.setRequestIsPost(false)
		.setUrl(this.url)
		.setRequestParams(me.params)
		.setPendingModel(false, null)
		.setBefore(function () {
			me.loadStatus = true;
		})
		.setComplete(function (json) {
			me.loadStatus = false;

			// 没有更多数据
			if (false === me.isFirstLoad && json.result.hasOwnProperty('totalPage')) {
				if (me.page >= json.result.totalPage + 1) {
					me.moreTraget.html(me.emptyMoreTemplate.replace('__MESSAGE__', me.emptyMoreMessage)).show();
					return false;
				}
			}
		})
		.setSuccess(function (json) {
			// 首次加载
			if (me.isFirstLoad) {
				// 列表数据不存在则认为无数据
				if (!$.trim(json.result.list)) {
					json.result.list = me.emptyTemplate.replace('__MESSAGE__', me.emptyMessage);

					// 重置首次加载状态
					me.isFirstLoad = true;
				} else {

					// 关闭首次加载
					me.isFirstLoad = false;
				}

				// 设置数据
				me.dataTarget.html(json.result.list);

				// 设置起始页码
				me.setPageStartIndex(me.pageStartIndex);
			}

			// 非首次加载
			else {
				// 则追加数据
				me.dataTarget.append(json.result.list);

				// 更多加载显示
				if (!json.result.list) {
					me.moreTraget.html(me.emptyMoreTemplate.replace('__MESSAGE__', me.emptyMoreMessage)).show();
				} else {
					me.moreTraget.html(me.moreTemplate.replace('__MESSAGE__', me.moreMessage)).show();
				}

				// 关闭首次加载
				me.isFirstLoad = false;
			}

			// 分页码累加
			me.page++;
			if (typeof me.completeCallback === 'function') {
				me.completeCallback.call(me);
			}
		})
		.setError(function (json) {
			me.isFirstLoad = true;
			me.dataTarget.html(me.errorTemplate.replace('__MESSAGE__', json.message));
			me.moreTraget.hide();
		})
		.request();

	return this;
};
/**
 * 执行
 * @param {Boolean} isRequest 是否执行请求
 * @return {BLoadData}
 */
BLoadData.prototype.run = function (isRequest) {
	var me    = this;
	isRequest = typeof isRequest == 'boolean' ? isRequest : true;

	// 更多展示容器
	if (this.moreTarget == null) {
		var $moreTarget = $('<div />').css({
			'padding'    : '10px',
			'text-align' : 'center',
			'display'    : 'none',
			'font-size'  : '12px',
			'color'      : '#999'
		});
		this.dataTarget.after($moreTarget);
		this.moreTraget = this.dataTarget.next('div');
		this.moreTraget.before('<div class="clearfix" />');
	}

	// 绑定滚动事件
	this.scrollTarget.on('scroll', function () {
		clearTimeout(me.timer);
		if (me.isShowAll) {
			return false;
		}

		if (!me.loadStatus) {
			var scrollTop    = me.scrollTarget.scrollTop();
			var scrollHeight = me.scrollTarget.height();
			if (scrollTop + me.windowHeight >= scrollHeight) {
				me.timer = setTimeout(function () {
					me.request();
				}, 100);
			}
		}
	});

	// 执行首次请求
	if (isRequest) {
		this.request();
	}

	return this;
};
/**
 * 执行重新加载数据
 * @return {BLoadData}
 */
BLoadData.prototype.reload = function () {
	this.isFirstLoad = true;
	this.setPageStartIndex(this.pageStartIndex);
	this.request();
	return this;
};

(function ($) {
	$.cookie = function (name, value, options) {
		if (typeof value != 'undefined') {
			options = options || {};
			if (value === null) {
				value           = '';
				options         = $.extend({}, options);
				options.expires = -1
			}

			var expires = '';
			if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
				var date;
				if (typeof options.expires == 'number') {
					date = new Date();
					date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000))
				} else {
					date = options.expires
				}

				expires = '; expires=' + date.toUTCString()
			}

			var path        = options.path ? '; path=' + (options.path) : '';
			var domain      = options.domain ? '; domain=' + (options.domain) : '';
			var secure      = options.secure ? '; secure' : '';
			document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('')
		} else {
			var cookieValue = null;
			if (document.cookie && document.cookie != '') {
				var cookies = document.cookie.split(';');
				for (var i = 0; i < cookies.length; i++) {
					var cookie = jQuery.trim(cookies[i]);
					if (cookie.substring(0, name.length + 1) == (name + '=')) {
						cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
						break
					}
				}
			}

			return cookieValue
		}
	};

	/**
	 * 微信支付
	 * @param {Object} payParams 支付参数
	 * @param {Function} success 成功
	 * @param {Function} error 失败
	 * @param {Function} cancel 取消
	 */
	$.weChatPay = function (payParams, success, error, cancel) {
		success      = success || window.bAnonymous;
		error        = error || window.bAnonymous;
		cancel       = cancel || window.bAnonymous;
		var callback = function () {
			if (!payParams) {
				error('微信支付参数异常');
				return;
			}
			WeixinJSBridge.invoke('getBrandWCPayRequest', payParams, function (res) {
				if (res.err_msg == "get_brand_wcpay_request:ok") {
					success();
				} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
					cancel();
				} else {
					error();
				}
			});
		};
		if (typeof WeixinJSBridge == "undefined") {
			if (document.addEventListener) {
				document.addEventListener('WeixinJSBridgeReady', callback, false);
			} else if (document.attachEvent) {
				document.attachEvent('WeixinJSBridgeReady', callback);
				document.attachEvent('onWeixinJSBridgeReady', callback);
			}
		} else {
			callback();
		}
	};

	/**
	 * 请求
	 * @return {BRequest}
	 */
	$.BRequest = function () {
		return new BRequest();
	};

	/**
	 * 强制转换成数字
	 * @param number
	 * @param isFloat
	 * @return number
	 */
	$.parseNumber = function (number, isFloat) {
		isFloat = typeof isFloat === 'boolean' ? isFloat : false;
		number  = number || 0;
		if (isFloat) {
			number = parseFloat(number);
		} else {
			number = parseInt(number);
		}
		return isNaN(number) ? 0 : number;
	};

	/**
	 * 将键值对转换成隐藏字段
	 * @param {Object} params 参数合集
	 * @param {Array} textKeys 属于大文本的字段
	 * @param {String} name 定义name命名空间
	 * @return {String}
	 */
	$.parseToHidden = function (params, name, textKeys) {
		textKeys   = textKeys || [];
		name       = name || '';
		var hidden = '';
		for (var key in params) {
			var field = key;
			var value = params[key] || '';
			if (name) {
				field = name + '[' + field + ']';
			}
			if (-1 !== textKeys.indexOf(key)) {
				hidden += '<textarea name="' + field + '" style="display: none;">' + value + '</textarea>';
			} else {
				hidden += '<input name="' + field + '" type="hidden" value="' + value + '" />';
			}
		}

		return hidden;
	};

	/**
	 * ajax显示
	 * @param {BRequest} bRequest 请求类
	 * @param {Function} parseCallback (Boolean isScript, String content)=String 解析回调
	 * @param {Function} successCallback (Object json) 成功回调
	 */
	$.ajaxDisplay = function (bRequest, parseCallback, successCallback) {
		bRequest        = bRequest || $.BRequest();
		successCallback = typeof successCallback === 'function' ? successCallback : bAnonymous;
		bRequest
			.isPost(false)
			.isCache(false)
			.setSuccess(function (json) {
				var html   = json.result.html;
				var script = json.result.script;
				if (typeof parseCallback === 'function') {
					html   = parseCallback(false, html);
					script = parseCallback(true, script);
				}

				$('[ajax-display="body"]').html(html);
				$('[ajax-display="script"]').remove();
				$('body').append('<script ajax-display="script">' + script + '<\/script>');

				successCallback.call(this, json);
			})
			.request();
	};

	/**
	 * 切换验证码
	 */
	$.fn.changeVerify = function () {
		$(this).on('click', function () {
			if (!$(this).attr('data-src')) {
				$(this).attr('data-src', $(this).attr('src'));
			}
			var src = $(this).attr('data-src');
			if (-1 === src.indexOf('?')) {
				src += '?__t=';
			} else {
				src += '&__t=';
			}

			$(this).attr('src', src + Math.random());
		});

		return this;
	};

	/**
	 * 获取name对象
	 * @param name
	 * @return {jQuery}
	 */
	$.fn.getName = function (name) {
		return $(this).find('[name="' + name + '"]');
	};

	/**
	 * 自动定位出错的表单
	 * @param {Object} json
	 * @param {Function} callback (Object json)
	 * @return {jQuery}
	 */
	$.fn.autoLocationForm = function (json, callback) {
		if (json.code == $.fn.autoLocationForm.code && json.hasOwnProperty('name')) {
			bDialog.toast(json.message);
			$(this).getName(json.name).focus();
			return this;
		}

		if (typeof callback === 'function') {
			callback.call(this, json);
		}
		return this;
	};
	$.fn.autoLocationForm.code = 400001;

	/**
	 * 执行自动提交
	 * @param {BRequest} bRequest 请求类
	 * @param {Function} before (jQuery $me) = Boolean 返回false阻止提交
	 * @param {Function} success (Object json, jQuery $me)
	 * @param {Function} error (Object json, jQuery $me)
	 * @param {Function} complete (Object json, jQuery $me) = boolean 返回false阻止success和error的执行
	 * @param {Boolean} autoLocationError 是否自动侦测错误
	 * @return {jQuery}
	 */
	$.fn.autoSubmit = function (bRequest, before, success, error, complete, autoLocationError) {
		autoLocationError    = typeof autoLocationError === 'boolean' ? autoLocationError : true;
		bRequest             = bRequest || $.BRequest();
		complete             = typeof complete === 'function' ? complete : BRequest.options.completeCallback;
		success              = typeof success === 'function' ? success : BRequest.options.successCallback;
		error                = typeof error === 'function' ? error : BRequest.options.errorCallback;
		before               = typeof before === 'function' ? before : BRequest.options.beforeCallback;
		var $me              = $(this).removeAttr('onsubmit');
		var method           = ($me.attr('method') || 'POST').toLocaleUpperCase();
		var url              = $me.attr('action') || document.URL;
		var $submit          = $me.find(':submit');
		var completeCallback = function (json) {
			$submit.prop('disabled', false).removeClass('disabled');
			return complete.call(this, json, $me);
		};
		var successCallback  = function (json) {
			success.call(this, json, $me);
		};
		var errorCallback    = function (json) {
			var re = this;

			if (autoLocationError) {
				$me.autoLocationForm(json, function () {
					error.call(re, json, $me);
				});
			} else {
				error.call(re, json, $me);
			}
		};
		var beforeCallback   = function () {
			var status = before.call(this, $me);
			if (false === status) {
				return false;
			}

			// 禁止按钮再次点击
			$submit.prop('disabled', true).addClass('disabled');
		};

		// 绑定提交事件
		$me.off('submit').on('submit', function () {
			bRequest.clearRequestParams();
			var params       = $me.serializeArray();
			var paramsLength = params.length;
			for (var i = 0; i < paramsLength; i++) {
				bRequest.addRequestParam(params[i].name, params[i].value);
			}

			bRequest.setComplete(completeCallback);
			bRequest.setSuccess(successCallback);
			bRequest.setError(errorCallback);
			bRequest.setBefore(beforeCallback);
			bRequest.setRequestIsPost((method == 'POST'));
			bRequest.setUrl(url);
			bRequest.request();

			return false;
		});

		return this;
	};
})(jQuery);
